<!--
 * @Description: tree
 * @Author: qingyang
 * @Date: 2023-11-10 19:05:29
 * @LastEditors: chenju
 * @LastEditTime: 2023-11-11 16:12:02
-->
<template>
  <div class="organization-tree">
    <div class="input-box">
      <el-input
        class="input-box-content"
        placeholder="组织名称"
        v-model="orgName"
        @input="handleSearch"
        clearable
      >
        <!-- :class="collapseState ? 'input-box__input--collapsed' : ''" -->
        <template #suffix>
          <CIcon type="c-xian-sousuo"></CIcon>
        </template>
      </el-input>
    </div>
    <div class="tree-box" v-loading="loading">
      <GTree
        :allow-drop="allowDrop"
        :allow-drag="allowDrag"
        :data="dataSource"
        :draggable="movePermission"
        default-expand-all
        node-key="id"
        @node-drag-end="handleDragEnd"
        :props="treeProps"
        @current-change="handleNodeClick"
        :expand-on-click-node="false"
        ref="treeRef"
        :filter-node-method="filterNode"
      >
        <template #rightIcon="{ data }" v-if="deletePermission || createPermission">
          <div class="textMark" v-if="data.tag">
            <el-tag class="org-tag textMark-tag" :class="`tag-${data.tag}`">
              {{ OrgTagMapEnum[data.tag] }}
            </el-tag>
          </div>
          <el-dropdown v-if="data.enable && data.organizationCode">
            <span class="handle-button">
              <CIcon type="c-xian-gengduoheng"></CIcon>
            </span>
            <template #dropdown>
              <!-- <el-dropdown-menu> -->
              <el-dropdown-item @click="remove(data)" v-if="data.isLeaf && deletePermission"
                >删除组织</el-dropdown-item
              >
              <el-dropdown-item @click="appendChild(data)" v-if="createPermission"
                >添加下属组织</el-dropdown-item
              >
              <!-- </el-dropdown-menu> -->
            </template>
          </el-dropdown>
        </template>

        <template #leftIcon="{ data }">
          <CIcon
            v-if="data.parentId === -1 ? false : true"
            type="c-xian-tuozhuai"
            class="tuozhuai"
          ></CIcon>
        </template>
      </GTree>
    </div>
  </div>
</template>
<script lang="ts">
export default {
  name: 'OrganizationTree'
};
</script>
<script lang="ts" setup>
import { defineProps, defineEmits, defineExpose, computed, watch, Ref, ref, PropType } from 'vue';
import { useMessage } from '@/hooks/useMessage';
import { GTree } from '@/components/GTree/index';
import type Node from 'element-plus/es/components/tree/src/model/node';
import type { AllowDropType } from 'element-plus/es/components/tree/src/tree.type';
import {
  deleteOrganization,
  getOrganizationTreeByUser,
  moveOrganization,
  postCheckExistTask,
  postCheckTips
} from '@/apis/system/organization';
import {
  GetOrganizationTreeResult,
  MoveOrganizationParams
} from '@/apis/system/model/organizationModel';
import { hasBtnPermission } from '@/directives/btnPermission';
import { store } from '@/store';
import formMitt from '@/hooks/mybus';
import { OrgTagMapEnum } from '@/constants/enum';
import { debounce } from 'lodash';

const props = defineProps({
  tree: {
    type: Array as PropType<GetOrganizationTreeResult[]>,
    default: () => {
      return [];
    }
  },
  collapseState: {
    type: Boolean,
    default: false
  }
});

const emit = defineEmits(['selectData', 'openDialong']);
let enableId: undefined | number;
//获取树列表数据
const dataSource = ref<GetOrganizationTreeResult[]>([]);
const orgName = ref('');
const loading = ref(false);
const refreshTree = async (id?: number, isParent?: boolean) => {
  if (!isParent) {
    // 如果不是父级传来的tree 重新通过接口获取
    const userId = store.state.user.userInfo.userId;
    let data = await getOrganizationTreeByUser(userId);
    dataSource.value = data;
  }
  if (!id) {
    // 如果id不存在，初始化第一个enble的id
    getEnableId(dataSource.value);
    id = enableId;
  }
  if (id || id === 0) {
    // ID存在才去跳转页面
    // 重置标志
    currentIsNew = false;
    setTimeout(() => {
      treeRef.value.treeRef.setCurrentKey(id);
      handleNodeClick(getDataById(id));
    }, 100);
  }
};
watch(
  () => props.tree,
  val => {
    dataSource.value = val;
    refreshTree(undefined, true);
  }
);
function getEnableId(data: any) {
  if (enableId || enableId === 0) return;
  if (data && data.length) {
    for (let i = 0; i < data.length; i++) {
      if (data[i].enable && !enableId) {
        enableId = data[i].id;
        return;
      } else {
        getEnableId(data[i].children);
      }
    }
  }
}

const treeRef: Ref = ref(null);
const customNodeClass = (data: any, node: Node) => {
  if (!data.enable) {
    return 'tree-disabled';
  }
  return null;
};
const treeProps = {
  label: 'organizationName',
  class: customNodeClass,
  disabled: (data: any) => {
    // 平台管理员能选全部
    return isPlatformAdmin.value ? !data.enable : !data.enable;
  }
};

const getDataById = (id?: number) => {
  let currentData: GetOrganizationTreeResult = dataSource.value[0];
  function getData(data: GetOrganizationTreeResult[]) {
    for (let i in data) {
      if (data[i].id == id) {
        return (currentData = data[i]);
      }
      if (data[i].children) {
        getData(data[i].children || []);
      }
    }
  }
  getData(dataSource.value);
  return currentData;
};

const handleDragEnd = async (
  draggingNode: Node,
  dropNode: Node,
  dropType: 'inner' | 'before' | 'after'
) => {
  console.log('tree drag end:', draggingNode, dropNode, dropType);
  let title = '';
  let parentId = '';
  if (dropType == 'inner') {
    title = `确认将 ${draggingNode.label} 添加到 ${dropNode.label} 的下属组织吗？`;
    parentId = dropNode.data.id;
  } else if (dropType == 'after') {
    if (dropNode.data.children && dropNode.data.children.length > 0) {
      title = `确认将 ${draggingNode.label} 添加到 ${dropNode.label} 的下属组织吗？`;
      parentId = dropNode.data.id;
    } else {
      title = `确认将 ${draggingNode.label} 移动到和 ${dropNode.label} 同级吗？`;
      parentId = dropNode.data.parentId;
    }
  }

  // const draggingNodeList = getNodeList(draggingNode.data as unknown as GetOrganizationTreeResult);

  // // source的列表
  // const orgCodes = draggingNodeList?.map(item => item.organizationCode) || [];

  // // target也要加上去
  // orgCodes.push(dropNode.data.organizationCode);
  const params = {
    organizationCode: draggingNode.data.organizationCode,
    targetOrgCode: dropNode.data.organizationCode
  };

  if (!params.organizationCode || !params.targetOrgCode) {
    return;
  }

  if (!title) {
    return;
  }

  try {
    loading.value = true;
    // 是否含有填报任务，如果有，则不能移动
    // const existTask = await postCheckExistTaskFn(orgCodes, 'MOVE');
    const tips = await postCheckTipsFn(params.organizationCode, 'MOVE', params.targetOrgCode);
    loading.value = false;
    // if (existTask) {
    //   refreshTree(draggingNode.data.id, false);
    // } else {
    //   // 拖动结束，请求接口
    //   dragReq(title, draggingNode, parentId);
    // }
    if (tips) {
      // 显示第一个确认框
      await createConfirm('确认移动组织？', tips, {
        iconType: 'warning',
        confirmButtonText: '确认'
      });
    }
    dragReq(title, draggingNode, parentId);
  } catch (error) {
    console.log('error', error);
    loading.value = false;
    refreshTree(draggingNode.data.id, false);
  }
};

/**
 * 拖动结束，请求接口
 */
function dragReq(title: string, draggingNode: Node, parentId: string) {
  createConfirm('确定移动组织？', `${title}移动组织后，组织及组织下属的所有子节点都会随之迁移。`, {
    iconType: 'warning',
    confirmButtonText: '确认',
    btnType: 'primary'
  })
    .then(async () => {
      const params: MoveOrganizationParams = {
        id: draggingNode.data.id,
        parentId
      };
      try {
        await moveOrganization(params);
        createMessage.success('移动成功');
      } finally {
        refreshTree(draggingNode.data.id);
      }
    })
    .catch(() => {
      refreshTree(draggingNode.data.id, false);
    });
}

function getNodeList(node: GetOrganizationTreeResult) {
  if (!node.children?.length) return [node];
  let nodeList = [node];
  for (let i = 0; i < node.children.length; i++) {
    const item = node.children[i];
    const res = getNodeList(item);
    if (res) nodeList = nodeList.concat(res);
  }
  return nodeList;
}

// 能不能拽
const allowDrag = (draggingNode: Node) => {
  return draggingNode.data.enable && draggingNode.data.organizationCode;
  // return !draggingNode.data.label.includes('Level three 3-1-1');
};
// 能不能放
const allowDrop = (draggingNode: Node, dropNode: Node, type: AllowDropType) => {
  if (type == 'prev') {
    return false;
  } else if (
    type == 'next' &&
    (draggingNode.data.parentId === dropNode.data.parentId ||
      draggingNode.data.parentId === dropNode.data.id)
  ) {
    return false;
  } else {
    return dropNode.data.enable;
  }
};

/**
 * 校验组织的任务是否存在
 * @param orgList
 */
async function postCheckExistTaskFn(orgList: string[], operationType: 'MOVE' | 'EDIT' | 'DELETE') {
  try {
    await postCheckExistTask(orgList, operationType);
    return Promise.resolve(false);
  } catch (error) {
    console.log('error', error);
    return Promise.resolve(true);
  }
}

/**
 * 校验组织引用信息
 * @param organizationCode
 * @param operationType
 * @param targetOrgCode
 */
async function postCheckTipsFn(
  organizationCode: string,
  operationType: 'MOVE' | 'EDIT' | 'DELETE',
  targetOrgCode?: string
) {
  try {
    const data = await postCheckTips(organizationCode, operationType, targetOrgCode);
    const tips = data?.join('<br />');
    return Promise.resolve(tips);
  } catch (error) {
    return Promise.reject(error);
  }
}

const { createConfirm, createMessage } = useMessage();
const remove = async (data: GetOrganizationTreeResult) => {
  if (currentIsNew) {
    cancelAddAlert(() => {
      refreshTree(data.id);
    });
  } else {
    try {
      loading.value = true;
      const tips = await postCheckTipsFn(data.organizationCode, 'DELETE');
      console.log(tips, 'tips');
      loading.value = false;

      if (tips) {
        // 显示第一个确认框
        await createConfirm('确认删除组织？', tips, {
          iconType: 'warning',
          confirmButtonText: '删除'
        });
      }

      // 显示第二个确认框
      await createConfirm('确认删除组织？', '删除后将清除本组织及下属节点的对应信息。', {
        iconType: 'warning',
        confirmButtonText: '删除'
      });

      loading.value = true;
      await deleteOrganization(data.id);
      createMessage.success('删除成功');
      refreshTree();
      loading.value = false;
    } catch (error) {
      console.log(error, 'error');
      loading.value = false;
    }
  }
};
let id = 1000;
let currentIsNew = false;

const cancelAddAlert = (fn?: any) => {
  createConfirm('确定取消创建组织？', '取消后将不保存已填写信息', {
    iconType: 'warning',
    confirmButtonText: '确定'
  })
    .then(() => {
      currentIsNew = false;
      if (fn) {
        fn();
      } else {
        refreshTree();
      }
    })
    .catch(() => {
      treeRef.value.treeRef.setCurrentKey(id);
    });
};
const dataId = ref<number>();
const cancel = () => {
  currentIsNew = false;
  refreshTree(dataId.value);
};
const cancelCatch = () => {
  treeRef.value.treeRef.setCurrentKey(id);
};
formMitt.on('cancelAddAlert', cancel);
formMitt.on('cancelCatch', cancelCatch);

// 增删
const appendChild = (data: GetOrganizationTreeResult) => {
  dataId.value = data.id;
  emit('openDialong');
  if (currentIsNew) {
    cancelAddAlert(() => {
      dataId.value = data.id;
      refreshTree(data.id);
    });
  } else {
    const newChild: GetOrganizationTreeResult = {
      id: ++id,
      organizationCode: '',
      organizationName: '',
      parentId: data.id,
      parentCode: '',
      rootCode: '',
      sort: '',
      level: 1,
      isLeaf: true,
      enable: true,
      children: []
    };

    if (!data.children) {
      data.children = [];
    }
    data.children.push(newChild);
    setTimeout(() => {
      treeRef.value.treeRef.setCurrentKey(newChild);
      handleNodeClick(newChild);
      currentIsNew = true;
    }, 100);
  }
};

const handleNodeClick = (data: GetOrganizationTreeResult) => {
  // 不是平台管理员的话，根据enable控制能不能点击
  if (!isPlatformAdmin.value && data.enable === false) return;
  if (data.enable) {
    if (currentIsNew) {
      cancelAddAlert(() => {
        refreshTree(data.id);
      });
    } else {
      emit('selectData', data);
    }
  }
};

// 移动组织的权限
const movePermission = computed(() => {
  return hasBtnPermission('ORGANIZATION_MOVE');
});
// 新增组织的权限
const createPermission = computed(() => {
  return hasBtnPermission('ORGANIZATION_CREATE');
});
// 删除组织的权限
const deletePermission = computed(() => {
  return hasBtnPermission('ORGANIZATION_DELETE');
});
// 是否是平台管理员
const isPlatformAdmin = computed(() => {
  return store.state.user.roles?.includes('ghg_admin') || false;
});

const filterNode = (value: string, data: GetOrganizationTreeResult) => {
  if (!value) return true;
  return data.organizationName.includes(value);
};
const handleSearch = debounce((val: string) => {
  treeRef.value?.treeRef?.filter(val);
}, 600);

defineExpose({
  refreshTree
});
</script>
<style lang="scss" scoped>
.organization-tree {
  width: 100%;
  transition: all 0.3s;
  // padding: 8px 12px;
  height: 100%;
  display: flex;
  flex-direction: column;

  .textMark {
    z-index: 9;
    position: absolute;
    top: 0;
    right: 0;
    background-color: #fff;
    width: 43px;
    height: 36px;

    &::before {
      content: '';
      background: linear-gradient(90deg, rgba(255, 255, 255, 0) 0%, #ffffff 100%);
      width: 12px;
      height: 36px;
      position: absolute;
      top: 0;
      left: -12px;
    }
    .textMark-tag {
      z-index: 9;
      position: absolute;
      top: 8px;
      left: 7px;
      display: flex;
      align-items: center;
      justify-content: center;
      width: 24px;
      height: 20px;
      font-size: 12px;
      border-radius: 3px;
    }
  }

  :deep(.el-tree-node__content) {
    position: relative;
    .tuozhuai {
      display: none;
      position: absolute;
      left: 8px;
      top: 8px;
    }
    .tuozhuai:hover {
      cursor: move;
      color: #000000 !important;
    }
  }
  :deep(.el-tree-node__content:hover) {
    .textMark {
      background-color: #f3f7fb;
      &::before {
        display: none;
      }
    }
  }

  :deep(.is-current:not(.tree-disabled) > .el-tree-node__content) {
    .textMark {
      background-color: #f3f7fb;
      &::before {
        display: none;
      }
    }
  }

  :deep(.el-tree-node:focus > .el-tree-node__content) {
    .textMark {
      background-color: #f3f7fb;
      &::before {
        display: none;
      }
    }
  }
  .tree-box {
    flex: 1;
    overflow: auto;
  }
}
:deep(.el-tree-node:not(.tree-disabled)) {
  .el-tree-node__content {
    &:hover {
      background: #f3f7fb !important;
      color: #435970 !important;
      .tuozhuai {
        display: block;
      }
    }
  }
}

.input-box {
  width: 100%;
  overflow: hidden;
  .input-box-content {
    margin: 12px 16px;
    width: calc(100% - 32px);
  }
}
// .el-dropdown-menu {
//   position: absolute !important;
//   top: 0 !important;
//   left: 0 !important;
// }
// :deep(.el-tree-node) {
//   .el-tree-node__content {
//     &:hover {
//       border: unset !important;
//       background: #f3f7fb !important;
//       color: #435970 !important;
//     }
//   }
// }
</style>
